#include "Game.h" 
#include "FileSystem.h"
//
namespace Buddha
{
	Game*	gGame;

	Game::Game()
		: _windowName("Game_Window"), _windowTitle("Game"), _clientWidth(800), _clientHeight(600),
		_windowX(0), _windowY(0), _hwnd(0), _fps(0.0f)
	{
		gGame = this;
	}

	Game::~Game()
	{

	}

	bool Game::doing()
	{
		if (!forePlay())
		{
			return false;
		}
		// Message Structure
		MSG msg;
		::ZeroMemory(&msg, sizeof(msg));
		// Loop until getting a WM_QUIT message
		while(true)
		{
			if (::PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
			{
				if (msg.message == WM_QUIT)
				{
					break;
				}
				::TranslateMessage(&msg);
				::DispatchMessage(&msg);
			}
			else
			{
				if (!play())
				{
					break;
				}
			}
		}
		// clean up
		if (!postPlay())
		{
			return false;
		}

		return true;
	}

	bool Game::forePlay()
	{
		if (!createWindow())
		{
			return false;
		}

		//
		if (!adjustClientArea())
		{
			return false;
		}

		return true;
	}

	bool Game::play()
	{
		static float last_time = (float)timeGetTime();
		float current_time = (float)timeGetTime();
		int count_frames = 0;
		++count_frames;
		if(current_time - last_time >= 1000)
		{
			_fps = 1000.0f * (float)count_frames / (current_time - last_time);
			last_time = current_time;
			count_frames = 0;
		}

		//
		if (!update())
		{
			return false;
		}

		//
		if (!render())
		{
			return false;
		}

		//
		return true;
	}

	bool Game::postPlay()
	{
		return true;
	}

	bool Game::createWindow()
	{
		// Fill out the WNDCLASS structure
		WNDCLASS wc;
		wc.style = CS_HREDRAW | CS_VREDRAW;
		wc.lpfnWndProc = _wndProc;
		wc.cbClsExtra = 0;
		wc.cbWndExtra = 0;
		wc.hInstance = ::GetModuleHandle(0);
		wc.hIcon = NULL;//::LoadIcon(0, IDI_APPLICATION);
		wc.hCursor = ::LoadCursor(0, IDC_ARROW);
		wc.hbrBackground = NULL;//static_cast<HBRUSH>(::GetStockObject(BLACK_BRUSH));
		wc.lpszMenuName = 0;
		wc.lpszClassName = _windowName.c_str();

		// Register the WNDCLASS description 
		if (!::RegisterClass(&wc))
		{
			return false;
		}

		// Create the window
		_hwnd = ::CreateWindow(_windowName.c_str(), _windowTitle.c_str(),
			WS_OVERLAPPEDWINDOW,
			_windowX, _windowY, _clientWidth, _clientHeight,
			0, 0, ::GetModuleHandle(0), 0);
		if (_hwnd ==0)
		{
			return false;
		}

		// Show the window
		::ShowWindow(_hwnd, SW_NORMAL);
		// Update the window
		::UpdateWindow(_hwnd);

		//
		return true;
	}

	LRESULT CALLBACK Game::_wndProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam )
	{
		switch(message)
		{
		case WM_CREATE:
			//
			
			break;

		case WM_KEYDOWN:
			switch(wParam)
			{
				// Destroy the window and Send the WM_DESTROY message
			case VK_ESCAPE:
				::DestroyWindow(hWnd);
				break;
			default:
				break;
			}
			return 0;

			//
		case WM_MOUSEMOVE:
			{ 
				//if (wParam & MK_CONTROL) { } // control key is down
				//if (wParam & MK_SHIFT) { }   // shift key is down
				//if (wParam & MK_MBUTTON) { } // middle mouse button is down
				//if (wParam & MK_LBUTTON) { } // left mouse button is down
				//if (wParam & MK_RBUTTON) { } // right mouse button is down
				//POINT point;
				//point.x = lParam & 0x0000ffff; // low order word = x
				//point.y = lParam >> 16;        // high order word = y
				//// do what you want with the point structure
			}
			break;


			//
		case WM_DROPFILES:
			{
				char file[256];
				DragQueryFile((HDROP)wParam, 0, file, 256);

				_dragDropFile = file;
				
				for (int i = 0; i < _dragDropFile.size(); ++i)
				{
					if(_dragDropFile[i] == '\\')
					{
						_dragDropFile[i] = '/';
					}
				}
				
				gGame->onDragAndDrop();
			}
			break;

			// Send the WM_QUIT message, terminating the message loop
		case WM_DESTROY:
			::PostQuitMessage(0);

			return 0;
		}
		// Forward any other messages we didn't handle above to the default window procedure
		return ::DefWindowProc(hWnd, message, wParam, lParam);
	}

	bool Game::adjustClientArea()
	{
		//
		RECT rect = {0, 0, _clientWidth, _clientHeight};
		if (!AdjustWindowRect(&rect, 
			GetWindowLong(_hwnd, GWL_STYLE), GetMenu(_hwnd) != NULL))
		{
			return false;
		}

		//
		unsigned int width = GetSystemMetrics(SM_CXFULLSCREEN);
		unsigned int height = GetSystemMetrics(SM_CYFULLSCREEN);

		//
		RECT rectWin;
		GetWindowRect(_hwnd, &rectWin);

		double x = (width - (rectWin.right - rectWin.left)) * 0.5;
		double y = (height - (rectWin.bottom - rectWin.top)) * 0.5;
		//
		if (!MoveWindow(_hwnd, (unsigned int)x, (unsigned int)y,
			rect.right - rect.left,
			rect.bottom - rect.top,
			true))
		{
			return false;
		}
		
		//
		return true;
	}

	bool Game::render()
	{
		//
		if (!foreRender())
		{
			return false;
		}

		//
		if (!rendering())
		{
			return false;
		}

		//
		if (!postRender())
		{
			return false;
		}

		//
		return true;
	}

	bool Game::update()
	{
		return true;
	}

	bool Game::foreRender()
	{
		return true;
	}

	bool Game::rendering()
	{
		return true;
	}

	bool Game::postRender()
	{
		return true;
	}

	void Game::setWindowTitle( const std::string& title )
	{
		_windowTitle = title;
	}

	void Game::onDragAndDrop()
	{

	}

	std::string Game::_dragDropFile("");

}